package com.linciping.gradle.inject

import android.app.Activity
import android.text.TextUtils
import android.util.Log
import android.util.LruCache
import android.view.View
import android.view.ViewGroup
import com.linciping.gradle.test.InjectorUtils

object ViewClickCount {

    private val pointViewCache: LruCache<Int, PointInfo> = LruCache(4)

    /**
     * 点击事件埋点方法
     */
    @JvmStatic
    fun onViewClick(view: View) {
        Log.e("ViewClickCount", "view click")
        val pointInfo: PointInfo? = pointViewCache[view.hashCode()]
        if (pointInfo != null) {
            Log.d("PointerEventDelegate", "page=${pointInfo.page}")
            Log.d("PointerEventDelegate", "path=${pointInfo.path}")
            return
        }
        //region详细埋点
        //步骤
        //1. 根据获取view的id名
        //2. 获取页面名称，如果id名是空的，还要构建view路径
        //3. 处理路径，并输入
        val viewEntryName = try {
            view.resources.getResourceEntryName(view.id)
        } catch (e: Exception) {
            ""
        }
        val pathList = mutableListOf<String>()
        val pageClass = getViewPageName(view, pathList, viewEntryName.isEmpty())
        val page = if (TextUtils.isEmpty(pageClass)) {
            "Inject"
        } else {
            pageClass!!.replace(".", "/")
        }
        val path = if (viewEntryName.isNullOrEmpty()) {
            val pathBuilder = StringBuilder()
            pathList.reversed().forEach { pathNode ->
                pathBuilder.append(pathNode, "/")
            }
            pathBuilder.append(view::class.java.simpleName)
            pathBuilder.toString()
        } else {
            "$page/$viewEntryName"
        }
        pointViewCache.put(view.hashCode(), PointInfo(page, path))
        Log.d("PointerEventDelegate", "page=${page}")
        Log.d("PointerEventDelegate", "path=${path}")
        //endregion
    }

    /**
     * 根据view获取页面类名
     * @param view 当前view
     * @param pathList 路径集合
     * @param needPath 是否需要构建路径
     */
    private fun getViewPageName(
        view: View,
        pathList: MutableList<String>,
        needPath: Boolean = false
    ): String? {
        //读取页面名称步骤
        //1. 先查看view是否有fragment名称标记，如果有代表是fragment，直接获取
        //2. 如果不是fragment，则找到对应的activity
        //3. 如果都是，则返回空
        val fragmentName = view.getTag(R.id.inject_fragment_name) as String?
        val activity = InjectorUtils.getActivityFromContext(view.context)
        return if (TextUtils.isEmpty(fragmentName)) {
            if (activity == null) {
                null
            } else {
                if (needPath) {
                    buildActivityPathByView(view, pathList, activity)
                }
                activity::class.java.name
            }
        } else {
            if (needPath) {
                buildFragmentPathByView(view, pathList)
            }
            fragmentName!!
        }
    }

    /**
     * 构建fragment view路径
     */
    private fun buildFragmentPathByView(view: View?, pathList: MutableList<String>) {
        if (view == null) return
        //步骤
        //1. 以当前view未起点，向上遍历
        //2. 找到当前view的位置，赋值
        //3. 如果没有fragment标记，表示到顶，结束循环
        var fragmentView: View = view
        var fragmentName = fragmentView.getTag(R.id.inject_fragment_name)
        while (fragmentName != null) {
            val parentView = addPath(fragmentView, pathList) ?: break
            fragmentView = parentView
            fragmentName = fragmentView.getTag(R.id.inject_fragment_name)
        }
    }


    /**
     * 构建activity view路径
     */
    private fun buildActivityPathByView(
        view: View?,
        pathList: MutableList<String>,
        activity: Activity
    ) {
        if (view == null) return
        //步骤
        //1. 以当前view未起点，向上遍历
        //2. 找到当前view的位置，赋值
        //3. 如果没有parent，表示到顶，结束循环
        val decorView = activity.window.decorView
        var activityView: View = view
        while (activityView != decorView) {
            val parentView = addPath(activityView, pathList) ?: break
            activityView = parentView
        }
    }


    /**
     * 添加路径
     */
    private fun addPath(childView: View, pathList: MutableList<String>): View? {
        val parentView = childView.parent
        if (parentView == null || parentView !is ViewGroup) {
            return null
        }
        pathList.add("${parentView::class.java.simpleName}[${parentView.indexOfChild(childView)}]")
        return parentView
    }

    fun sample() {
        val test = "test"
        println(test)
    }
}